package com.yxhl.zoume.core.expresscar.fragment;

import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.afollestad.materialdialogs.MaterialDialog;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.jakewharton.rxbinding.view.RxView;
import com.yxhl.protobuf.MpvModel;
import com.yxhl.protobuf.OrderBizType;
import com.yxhl.protobuf.RentalTime;
import com.yxhl.zoume.R;
import com.yxhl.zoume.ZouMeApplication;
import com.yxhl.zoume.common.info.ToolbarType;
import com.yxhl.zoume.common.ui.fragment.BaseFragment;
import com.yxhl.zoume.core.car.view.common.GetRentCarTimeView;
import com.yxhl.zoume.core.car.view.common.VehicleShowView;
import com.yxhl.zoume.core.expresscar.activity.ExpressCarContainerActivity;
import com.yxhl.zoume.core.expresscar.adapter.VehicleAdapter;
import com.yxhl.zoume.core.expresscar.event.RentHourlyVehicleSelectEvent;
import com.yxhl.zoume.core.expresscar.model.ExpressCarRentTimePicker;
import com.yxhl.zoume.core.expresscar.model.ExpressCarZMTimePicker;
import com.yxhl.zoume.core.expresscar.presenter.CreateExpressCarOrderPresenter;
import com.yxhl.zoume.core.expresscar.presenter.QueryVehiclePresenter;
import com.yxhl.zoume.core.expresscar.presenter.RentHourlyTimeQueryPresenter;
import com.yxhl.zoume.core.expresscar.view.CreateExpressCarOrderView;
import com.yxhl.zoume.core.expresscar.view.QueryPriceAndDistanceView;
import com.yxhl.zoume.core.func.map.ui.event.SelectedPOIEvent;
import com.yxhl.zoume.core.func.timepicker.presenter.ZMTimePickerPresenter;
import com.yxhl.zoume.core.func.timepicker.view.ZMTimePickerView;
import com.yxhl.zoume.core.officialcar.presenter.RentHourlyTimePickerPresenter;
import com.yxhl.zoume.core.specialcar.model.CarLocationMapEntrance;
import com.yxhl.zoume.di.component.car.ExpressCarComponent;
import com.yxhl.zoume.utils.PromptUtils;
import com.yxhl.zoume.utils.ZMDialog;
import com.yxhl.zoume.utils.permission.PermissionHelper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.OnClick;
import rx.Subscription;
import rx.functions.Action1;

/**
 * Author：zhongshan   
 * Date：2016/12/06 14:15      
 * Description：专车－分时租车
 */
public class RentHourlyExpressCarFragment extends BaseFragment implements ZMTimePickerView, GetRentCarTimeView,
        VehicleShowView, CreateExpressCarOrderView, QueryPriceAndDistanceView {

    @BindView(R.id.tv_include_get_in_location)
    TextView mGetInLocationTv;
    @BindView(R.id.tv_include_reservation_time)
    TextView mReservationTimeTv;
    @BindView(R.id.tv_include_rent_car_time)
    TextView mRentCarTimeTv;
    @BindView(R.id.iv_fragment_rent_hourly_express_car_previous)
    ImageView mCarPreviousIv;
    @BindView(R.id.rv_express_car)
    RecyclerView mRecyclerView;
    @BindView(R.id.iv_fragment_rent_hourly_express_car_next)
    ImageView mCarNextIv;
    @BindView(R.id.tv_fragment_rent_hourly_express_car_description)
    TextView mRentHourlyDescriptionTv;
    @BindView(R.id.btn_fragment_rent_hourly_submit)
    Button mRentSubmitBtn;
    @BindView(R.id.tv_price_detail)
    TextView mPriceDescriptionTv;
    @BindView(R.id.iv_price_rules)
    ImageView mPriceRulesIv;

    @Inject
    ZMTimePickerPresenter mZMTimePickerPresenter;
    @Inject
    RentHourlyTimePickerPresenter mRentHourlyTimePickerPresenter;
    @Inject
    RentHourlyTimeQueryPresenter mRentHourlyTimeQueryPresenter;
    @Inject
    QueryVehiclePresenter mQueryVehiclePresenter;
    @Inject
    CreateExpressCarOrderPresenter mCreateExpressCarOrderPresenter;

    private ExpressCarComponent component;
    private Subscription mGetInSubscription;
    private VehicleAdapter adapter;
    private HashMap<String, String> mRentCarDescriptionMap;
    private MaterialDialog loadingDialog;
    private String vehicleType;
    private Integer partTime;

    public static RentHourlyExpressCarFragment newInstance() {
        RentHourlyExpressCarFragment fragment = new RentHourlyExpressCarFragment();
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);
        mZMTimePickerPresenter.attachView(this);
        mRentHourlyTimeQueryPresenter.attachView(this);
        mRentHourlyTimePickerPresenter.attachView(this);
        mQueryVehiclePresenter.attachView(this);
        mCreateExpressCarOrderPresenter.attachView(this);
        initView();
        setRxViewClick();
        return view;
    }

    private void initView() {
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        mRecyclerView.setLayoutManager(linearLayoutManager);
        adapter = new VehicleAdapter(OrderBizType.SPECIAL_BUS_TIME);
        mRecyclerView.setAdapter(adapter);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        onVehicleClickRxBusEvent();
        mQueryVehiclePresenter.queryOfficialCarDisplayData(OrderBizType.SPECIAL_BUS_TIME);
    }

    @Override
    protected void initializeInjector() {
        component = getComponent(ExpressCarComponent.class);
        component.inject(this);
    }

    @Override
    protected int getLayoutResId() {
        return R.layout.fragment_rent_hourly_express_car;
    }

    @Override
    protected void setupToolBar() {
        if (mActivity instanceof ExpressCarContainerActivity) {
            ExpressCarContainerActivity containerActivity = ((ExpressCarContainerActivity) mActivity);
            containerActivity.changeToolbarInto(ToolbarType.RENT_HOURLY);
        }
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (!hidden)
            setupToolBar();
    }

    @OnClick(R.id.tv_include_get_in_location)
    void onGetInLocationClick() {
        onGetInRxBusEvent();
        if (PermissionHelper.checkLocationPermission(mActivity)) {
            getAppComponent().navigator().navigateToCarLoactionMapSelectActivity(mActivity, CarLocationMapEntrance.EXPRESS_CAR_RENT_HOURLY_GET_IN);
        } else {
            PermissionHelper.takeLocationPermission(this, PermissionHelper.REQUEST_CODE_EXPRESS_CAR_RENT_HOURLY_GET_IN_LOCATION);
        }
    }

    @OnClick(R.id.tv_include_reservation_time)
    void onReservationClick() {
        mZMTimePickerPresenter.showZMTimePicker(ExpressCarZMTimePicker.class);
    }

    @OnClick(R.id.tv_include_rent_car_time)
    void onRentCarTimeClick() {
        mRentHourlyTimePickerPresenter.showRentHourlyTimePicker(ExpressCarRentTimePicker.class);
    }

    @OnClick(R.id.iv_fragment_rent_hourly_express_car_previous)
    void onPreviousVehicleClick() {
        mRecyclerView.scrollToPosition(0);
    }

    @OnClick(R.id.iv_fragment_rent_hourly_express_car_next)
    void onNextVehicleClick() {
        mRecyclerView.scrollToPosition(mRecyclerView.getAdapter().getItemCount() - 1);
    }

    private void setRxViewClick() {
        RxView.clicks(mRentSubmitBtn)
                .throttleFirst(3000, TimeUnit.MILLISECONDS)
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        mCreateExpressCarOrderPresenter.createExpressCarOrder(OrderBizType.SPECIAL_BUS_TIME);
                    }
                });
    }

    @OnClick(R.id.iv_price_rules)
    void onPriceRulesClick() {
        if (partTime!=null){
            ZouMeApplication.application.getAppComponent().navigator().navigateToCarPricingRulesActivity(mActivity, OrderBizType.SPECIAL_BUS_TIME, vehicleType, partTime);
        }else {
            PromptUtils.showShort(mActivity,"请选择租车时长");
        }
    }

    private void onGetInRxBusEvent() {
        if (mGetInSubscription != null && !mGetInSubscription.isUnsubscribed()) {
            mGetInSubscription.unsubscribe();
        }
        mGetInSubscription = toSubscription(SelectedPOIEvent.class,
                new Action1<SelectedPOIEvent>() {
                    @Override
                    public void call(SelectedPOIEvent selectedPOIEvent) {
                        //处理选中数据
                        handleGetInSelectedPOIEvent(selectedPOIEvent, mGetInLocationTv);
                        //数据完整性检查
                        checkCompleteData();
                        //取消订阅关系
                        if (mGetInSubscription != null && !mGetInSubscription.isUnsubscribed()) {
                            mGetInSubscription.unsubscribe();
                        }
                    }
                },
                new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        onGetInRxBusEvent();
                    }
                }
        );
        //选择上车地点
        getSubscription().add(mGetInSubscription);
    }

    private void handleGetInSelectedPOIEvent(SelectedPOIEvent selectedPOIEvent, TextView getInLocationTv) {
        PoiItem poiItem = selectedPOIEvent.getPoiItem();
        if (poiItem != null) {
            String title = poiItem.getTitle();
            getInLocationTv.setText(title);

            //查询距离和价格 准备数据
            LatLonPoint latLonPoint = poiItem.getLatLonPoint();
            if (latLonPoint != null) {
                String lat = String.valueOf(latLonPoint.getLatitude());
                String lng = String.valueOf(latLonPoint.getLongitude());
                mRentHourlyTimeQueryPresenter.setLat(lat).setLng(lng);
                mCreateExpressCarOrderPresenter.setLat(lat).setLng(lng).setStartLocation(title);
            }
        }
    }

    @Override
    public void renderZMTimePickerOptionSelectResult(String zmTimePickerSimpleName, String options1, String options2, String options3) {
        if (ExpressCarZMTimePicker.class.getSimpleName().equals(zmTimePickerSimpleName)) {
            mCreateExpressCarOrderPresenter.handleZMTimePickerSelectResult(options1, options2, options3);
            mRentHourlyTimeQueryPresenter.handleZMTimePickerSelectResult(options1, options2, options3);
            mReservationTimeTv.setText(options1 + " " + options2 + " " + options3);
            checkCompleteData();
        } else if (ExpressCarRentTimePicker.class.getSimpleName().equals(zmTimePickerSimpleName)) {
            mRentCarTimeTv.setText(options1);
            partTime = Integer.valueOf(handleRentHourlyTimePickerSelectResult(options1));
            mRentHourlyTimeQueryPresenter.setPartTime(partTime);
            checkCompleteData();
            mCreateExpressCarOrderPresenter.handleRentHourlyTimePickerSelectResult(options1);
        }
    }


    @Override
    public void renderRentCarTimeOnSuccess(List<RentalTime> rentalTimesList) {
        mRentCarDescriptionMap = new HashMap<>();
        ArrayList<String> optional1List = new ArrayList<>();

        for (RentalTime rentalTime : rentalTimesList) {
            String rentalTimeDesc = rentalTime.getDesc();
            String partTime = rentalTime.getPartTime();
            String rentalKey = "租车" + partTime + "小时";
            if (rentalTimeDesc != null) {
                optional1List.add(rentalKey);
            }
            mRentCarDescriptionMap.put(rentalKey, rentalTimeDesc);
        }
        mRentHourlyTimePickerPresenter.setOptions1List(optional1List);
    }


    public String handleRentHourlyTimePickerSelectResult(String options1) {
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(options1);
        if (matcher.find()) {
            return matcher.group();
        } else {
            return "4";
        }
    }

    @Override
    public void renderVehicleModelDataOnSuccess(List<MpvModel> vehicleModelsList) {
        adapter.setVehicleModels(vehicleModelsList);
    }

    @Override
    public void renderVehicleModelDataOnFailure(String msg) {
        PromptUtils.show(mActivity, msg, Toast.LENGTH_SHORT);
    }

    @Override
    public void renderVehicleModeDataOnError(String errorMsg) {
        PromptUtils.show(mActivity, R.string.net_error, Toast.LENGTH_SHORT);
    }

    private void onVehicleClickRxBusEvent() {
        getSubscription().add(toSubscription(RentHourlyVehicleSelectEvent.class,
                new Action1<RentHourlyVehicleSelectEvent>() {
                    @Override
                    public void call(RentHourlyVehicleSelectEvent event) {
                        vehicleType = event.getVehicleType();
                        mCreateExpressCarOrderPresenter.setVehicleType(vehicleType);
                        mRentHourlyTimeQueryPresenter.setVehicleType(vehicleType);
                        checkCompleteData();
                    }
                },
                new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        onVehicleClickRxBusEvent();
                    }
                }));
    }

    private void checkCompleteData() {
        String getInLocation = mGetInLocationTv.getText().toString();
        String reservationTime = mReservationTimeTv.getText().toString();
        String rentCarTime = mRentCarTimeTv.getText().toString();

        if (TextUtils.isEmpty(getInLocation)
                || TextUtils.isEmpty(rentCarTime)
                || TextUtils.isEmpty(reservationTime)
                || !(adapter != null && adapter.isVehicleSelected())) {
            return;
        }
        mRentHourlyTimeQueryPresenter.queryPriceAndDistance(OrderBizType.SPECIAL_BUS_TIME);
        mRentSubmitBtn.setEnabled(true);
    }

    @Override
    public void renderExpressCarOrderOnSuccess(String orderId) {
        getAppComponent().navigator().navigateToExpressCarScheduleActivity(mActivity, orderId);
    }

    @Override
    public void renderExpressCarOrderOnFailure(String failureMsg) {
        PromptUtils.showShort(getContext(), failureMsg);
        showWaitingDialog(false);
    }

    @Override
    public void renderExpressCarOrderOnError(String errorMsg) {
        PromptUtils.showShort(getContext(), getString(R.string.net_error));
    }

    @Override
    public void showWaitingDialog(boolean needShow) {
        if (needShow) {
            loadingDialog = ZMDialog.getLoadingDialog(mActivity);
        } else {
            if (loadingDialog != null) {
                loadingDialog.dismiss();
            }
        }
    }

    @Override
    public void renderQueryPriceAndDistanceOnSuccess(String runKm, String runMin, String totalFee, String description) {
        mCreateExpressCarOrderPresenter.setMileage(runKm).setTotalDuration(runMin).setTotalFee(Double.valueOf(totalFee));
        if (totalFee != null && !("0").equals(totalFee) && !("0.0").equals(totalFee) && !("0.00").equals(totalFee)) {
            //约34.21元
            String source = "约" + totalFee + "元";
            SpannableString spannableString = new SpannableString(source);
            spannableString.setSpan(new AbsoluteSizeSpan(60), 1, source.length() - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            spannableString.setSpan(new ForegroundColorSpan(Color.RED), 1, source.length() - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            mPriceDescriptionTv.setText(spannableString);
        }
        if (!TextUtils.isEmpty(description)) {
            mRentHourlyDescriptionTv.setText(description);
        }
    }

    @Override
    public void renderQueryPriceAndDistanceOnFailure(String failureMsg) {
        PromptUtils.showShort(mActivity, failureMsg);
    }

    @Override
    public void renderQueryPriceAndDistanceOnError(String errorMsg) {
        PromptUtils.showShort(mActivity, getString(R.string.net_error));
    }

    @Override
    public void onPause() {
        super.onPause();
    }
}
